// bind.h

#ifndef _BIND_H__
#define _BIND_H__

#include <utility>

struct _storage0
{
};

template<class T1>
struct _storage1
{
	explicit _storage1(T1 a1) :
			t1(a1)
	{
	}
	T1 t1;
};

template<class T1, class T2>
struct _storage2
{
	_storage2(T1 a1, T2 a2) :
			t1(a1), t2(a2)
	{
	}
	T1 t1;
	T2 t2;
};

template<class T1, class T2, class T3>
struct _storage3
{
	_storage3(T1 a1, T2 a2, T3 a3) :
			t1(a1), t2(a2), t3(a3)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
};

template<class T1, class T2, class T3, class T4>
struct _storage4
{
	_storage4(T1 a1, T2 a2, T3 a3, T4 a4) :
			t1(a1), t2(a2), t3(a3), t4(a4)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
	T4 t4;
};

template<class T1, class T2, class T3, class T4, class T5>
struct _storage5
{
	_storage5(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) :
			t1(a1), t2(a2), t3(a3), t4(a4), t5(a5)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
	T4 t4;
	T5 t5;
};

template<class T1, class T2, class T3, class T4, class T5, class T6>
struct _storage6
{
	_storage6(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) :
			t1(a1), t2(a2), t3(a3), t4(a4), t5(a5), t6(a6)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
	T4 t4;
	T5 t5;
	T6 t6;
};

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
struct _storage7
{
	_storage7(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) :
			t1(a1), t2(a2), t3(a3), t4(a4), t5(a5), t6(a6), t7(a7)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
	T4 t4;
	T5 t5;
	T6 t6;
	T7 t7;
};

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
		class T8>
struct _storage8
{
	_storage8(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) :
			t1(a1), t2(a2), t3(a3), t4(a4), t5(a5), t6(a6), t7(a7), t8(a8)
	{
	}
	T1 t1;
	T2 t2;
	T3 t3;
	T4 t4;
	T5 t5;
	T6 t6;
	T7 t7;
	T8 t8;
};

template<int i>
struct int2type
{
	enum
	{
		value = i
	};
};

typedef int2type<1> place_holder1;
typedef int2type<2> place_holder2;
typedef int2type<3> place_holder3;
typedef int2type<4> place_holder4;
typedef int2type<5> place_holder5;
typedef int2type<6> place_holder6;
typedef int2type<7> place_holder7;
typedef int2type<8> place_holder8;

static place_holder1 _1;
static place_holder2 _2;
static place_holder3 _3;
static place_holder4 _4;
static place_holder5 _5;
static place_holder6 _6;
static place_holder7 _7;
static place_holder8 _8;

struct _call0: public _storage0
{
	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1>
struct _call1: public _storage1<T1>
{
	_call1(T1 t1) :
			_storage1<T1>(t1)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2>
struct _call2: public _storage2<T1, T2>
{

	_call2(T1 t1, T2 t2) :
			_storage2<T1, T2>(t1, t2)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3>
struct _call3: public _storage3<T1, T2, T3>
{

	_call3(T1 t1, T2 t2, T3 t3) :
			_storage3<T1, T2, T3>(t1, t2, t3)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3, class T4>
struct _call4: public _storage4<T1, T2, T3, T4>
{

	_call4(T1 t1, T2 t2, T3 t3, T4 t4) :
			_storage4<T1, T2, T3, T4>(t1, t2, t3, t4)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	T4 operator [](place_holder4)
	{
		return this->t4;
	}

	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3, class T4, class T5>
struct _call5: public _storage5<T1, T2, T3, T4, T5>
{

	_call5(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) :
			_storage5<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	T4 operator [](place_holder4)
	{
		return this->t4;
	}

	T5 operator [](place_holder5)
	{
		return this->t5;
	}
	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3, class T4, class T5, class T6>
struct _call6: public _storage6<T1, T2, T3, T4, T5, T6>
{

	_call6(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) :
			_storage6<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	T4 operator [](place_holder4)
	{
		return this->t4;
	}

	T5 operator [](place_holder5)
	{
		return this->t5;
	}

	T6 operator [](place_holder6)
	{
		return this->t6;
	}
	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
struct _call7: public _storage7<T1, T2, T3, T4, T5, T6, T7>
{

	_call7(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) :
			_storage7<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	T4 operator [](place_holder4)
	{
		return this->t4;
	}

	T5 operator [](place_holder5)
	{
		return this->t5;
	}

	T6 operator [](place_holder6)
	{
		return this->t6;
	}

	T7 operator [](place_holder7)
	{
		return this->t7;
	}

	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
		class T8>
struct _call8: public _storage8<T1, T2, T3, T4, T5, T6, T7, T8>
{

	_call8(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) :
			_storage8<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6,
					t7, t8)
	{
	}

	T1 operator [](place_holder1)
	{
		return this->t1;
	}

	T2 operator [](place_holder2)
	{
		return this->t2;
	}

	T3 operator [](place_holder3)
	{
		return this->t3;
	}

	T4 operator [](place_holder4)
	{
		return this->t4;
	}

	T5 operator [](place_holder5)
	{
		return this->t5;
	}

	T6 operator [](place_holder6)
	{
		return this->t6;
	}

	T7 operator [](place_holder7)
	{
		return this->t7;
	}

	T8 operator [](place_holder8)
	{
		return this->t8;
	}
	template<class T>
	T operator [](T t)
	{
		return t;
	}
};

template<class R>
struct invoke0
{
	typedef invoke0<R> _self;

	invoke0()
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f();
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f();
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)();
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)();
		}
	};
};

template<class R, class T1>
struct invoke1: public _storage1<T1>
{
	typedef invoke1<R, T1> _self;

	invoke1(T1 t1) :
			_storage1<T1>(t1)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1]);
		}
	};
};

template<class R, class T1, class T2>
struct invoke2: public _storage2<T1, T2>
{
	typedef invoke2<R, T1, T2> _self;

	invoke2(T1 t1, T2 t2) :
			_storage2<T1, T2>(t1, t2)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2]);
		}
	};
};

template<class R, class T1, class T2, class T3>
struct invoke3: public _storage3<T1, T2, T3>
{
	typedef invoke3<R, T1, T2, T3> _self;

	invoke3(T1 t1, T2 t2, T3 t3) :
			_storage3<T1, T2, T3>(t1, t2, t3)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3]);
		}
	};
};

template<class R, class T1, class T2, class T3, class T4>
struct invoke4: public _storage4<T1, T2, T3, T4>
{
	typedef invoke4<R, T1, T2, T3, T4> _self;

	invoke4(T1 t1, T2 t2, T3 t3, T4 t4) :
			_storage4<T1, T2, T3, T4>(t1, t2, t3, t4)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3], c[o->t4]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3], c[o->t4]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4]);
		}
	};
};

template<class R, class T1, class T2, class T3, class T4, class T5>
struct invoke5: public _storage5<T1, T2, T3, T4, T5>
{
	typedef invoke5<R, T1, T2, T3, T4, T5> _self;

	invoke5(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) :
			_storage5<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4], c[o->t5]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3], c[o->t4],
					c[o->t5]);
		}
	};
};

template<class R, class T1, class T2, class T3, class T4, class T5, class T6>
struct invoke6: public _storage6<T1, T2, T3, T4, T5, T6>
{
	typedef invoke6<R, T1, T2, T3, T4, T5, T6> _self;

	invoke6(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) :
			_storage6<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4], c[o->t5], c[o->t6]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3], c[o->t4],
					c[o->t5], c[o->t6]);
		}
	};
};

template<class R, class T1, class T2, class T3, class T4, class T5, class T6,
		class T7>
struct invoke7: public _storage7<T1, T2, T3, T4, T5, T6, T7>
{
	typedef invoke7<R, T1, T2, T3, T4, T5, T6, T7> _self;

	invoke7(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) :
			_storage7<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6],
					c[o->t7]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6],
					c[o->t7]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4], c[o->t5], c[o->t6], c[o->t7]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3], c[o->t4],
					c[o->t5], c[o->t6], c[o->t7]);
		}
	};
};

template<class R, class T1, class T2, class T3, class T4, class T5, class T6,
		class T7, class T8>
struct invoke8: public _storage8<T1, T2, T3, T4, T5, T6, T7, T8>
{
	typedef invoke8<R, T1, T2, T3, T4, T5, T6, T7, T8> _self;

	invoke8(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) :
			_storage8<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6,
					t7, t8)
	{
	}

	template<class F, class C>
	R run(F f, C c)
	{
		return _proxy<R, F, C>::run(f, c, this);
	}

	template<class Ret, class F, class C>
	struct _proxy
	{
		static Ret run(F f, C c, _self* o)
		{
			return f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6],
					c[o->t7], c[o->t8]);
		}
	};

	template<class F, class C>
	struct _proxy<void, F, C>
	{
		static void run(F f, C c, _self* o)
		{
			f(c[o->t1], c[o->t2], c[o->t3], c[o->t4], c[o->t5], c[o->t6],
					c[o->t7], c[o->t8]);
		}
	};

	template<class Ret, class O, class F, class C>
	struct _proxy<Ret, std::pair<O, F>, C>
	{
		static Ret run(const std::pair<O, F>& pair, C c, _self* o)
		{
			return ((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3],
					c[o->t4], c[o->t5], c[o->t6], c[o->t7], c[o->t8]);
		}
	};

	template<class O, class F, class C>
	struct _proxy<void, std::pair<O, F>, C>
	{
		static void run(const std::pair<O, F>& pair, C c, _self* o)
		{
			((*pair.first).*pair.second)(c[o->t1], c[o->t2], c[o->t3], c[o->t4],
					c[o->t5], c[o->t6], c[o->t7], c[o->t8]);
		}
	};
};

template<class R, class F, class I>
class bind_t
{
public:
	bind_t(F f, I i) :
			f_(f), invoke_(i)
	{
	}

	R operator ()()
	{
		return invoke_.run(f_, _call0());
	}

	template<class T1>
	R operator ()(T1 t1)
	{
		return invoke_.run(f_, _call1<T1>(t1));
	}

	template<class T1, class T2>
	R operator ()(T1 t1, T2 t2)
	{
		return invoke_.run(f_, _call2<T1, T2>(t1, t2));
	}

	template<class T1, class T2, class T3>
	R operator ()(T1 t1, T2 t2, T3 t3)
	{
		return invoke_.run(f_, _call3<T1, T2, T3>(t1, t2, t3));
	}

	template<class T1, class T2, class T3, class T4>
	R operator ()(T1 t1, T2 t2, T3 t3, T4 t4)
	{
		return invoke_.run(f_, _call4<T1, T2, T3, T4>(t1, t2, t3, t4));
	}

	template<class T1, class T2, class T3, class T4, class T5>
	R operator ()(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
	{
		return invoke_.run(f_, _call5<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5));
	}

	template<class T1, class T2, class T3, class T4, class T5, class T6>
	R operator ()(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
	{
		return invoke_.run(f_,
				_call6<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6));
	}

	template<class T1, class T2, class T3, class T4, class T5, class T6,
			class T7>
	R operator ()(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
	{
		return invoke_.run(f_,
				_call7<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7));
	}

	template<class T1, class T2, class T3, class T4, class T5, class T6,
			class T7, class T8>
	R operator ()(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
	{
		return invoke_.run(f_,
				_call8<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6,
						t7, t8));
	}
private:
	F f_;
	I invoke_;
};

template<class R, class F>
bind_t<R, F, invoke0<R> > bind(F f)
{
	return bind_t<R, F, invoke0<R> >(f, invoke0<R>());
}

template<class R, class F, class T1>
bind_t<R, F, invoke1<R, T1> > bind(F f, T1 t1)
{
	return bind_t<R, F, invoke1<R, T1> >(f, invoke1<R, T1>(t1));
}

template<class R, class F, class T1, class T2>
bind_t<R, F, invoke2<R, T1, T2> > bind(F f, T1 t1, T2 t2)
{
	return bind_t<R, F, invoke2<R, T1, T2> >(f, invoke2<R, T1, T2>(t1, t2));
}

template<class R, class F, class T1, class T2, class T3>
bind_t<R, F, invoke3<R, T1, T2, T3> > bind(F f, T1 t1, T2 t2, T3 t3)
{
	return bind_t<R, F, invoke3<R, T1, T2, T3> >(f,
			invoke3<R, T1, T2, T3>(t1, t2, t3));
}

template<class R, class F, class T1, class T2, class T3, class T4>
bind_t<R, F, invoke4<R, T1, T2, T3, T4> > bind(F f, T1 t1, T2 t2, T3 t3, T4 t4)
{
	return bind_t<R, F, invoke4<R, T1, T2, T3, T4> >(f,
			invoke4<R, T1, T2, T3, T4>(t1, t2, t3, t4));
}

template<class R, class F, class T1, class T2, class T3, class T4, class T5>
bind_t<R, F, invoke5<R, T1, T2, T3, T4, T5> > bind(F f, T1 t1, T2 t2, T3 t3,
		T4 t4, T5 t5)
{
	return bind_t<R, F, invoke5<R, T1, T2, T3, T4, T5> >(f,
			invoke5<R, T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5));
}

template<class R, class F, class T1, class T2, class T3, class T4, class T5,
		class T6>
bind_t<R, F, invoke6<R, T1, T2, T3, T4, T5, T6> > bind(F f, T1 t1, T2 t2, T3 t3,
		T4 t4, T5 t5, T6 t6)
{
	return bind_t<R, F, invoke6<R, T1, T2, T3, T4, T5, T6> >(f,
			invoke6<R, T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6));
}

template<class R, class F, class T1, class T2, class T3, class T4, class T5,
		class T6, class T7>
bind_t<R, F, invoke7<R, T1, T2, T3, T4, T5, T6, T7> > bind(F f, T1 t1, T2 t2,
		T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{
	return bind_t<R, F, invoke7<R, T1, T2, T3, T4, T5, T6, T7> >(f,
			invoke7<R, T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7));
}

template<class R, class F, class T1, class T2, class T3, class T4, class T5,
		class T6, class T7, class T8>
bind_t<R, F, invoke8<R, T1, T2, T3, T4, T5, T6, T7, T8> > bind(F f, T1 t1,
		T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{
	return bind_t<R, F, invoke8<R, T1, T2, T3, T4, T5, T6, T7, T8> >(f,
			invoke8<R, T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6,
					t7, t8));
}

#endif //_BIND_H__
